﻿using Infrastructure;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;

namespace Vision.AlgBase
{
    public sealed class AddInContainer 
    {
        private AddInContainer() { }

        public static AddInContainer Instance 
        {
            get
            {
                lock (muxe)
                {
                    if (_instance == null)
                    { 
                        _instance = new AddInContainer(); 
                    }
                    return _instance;
                }             
            }
        }
        private static AddInContainer _instance = null;

        [ImportMany(typeof(IAlg))]
        public IEnumerable<Lazy<IAlg, IServiceData>> Tools { get; private set; }

        public bool IsInit { get; private set; }

        #region 公有函数
        public void LoadAddIn()
        {
            AggregateCatalog catalog = new AggregateCatalog();
            string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), SerarchDll);
            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var path in files)
            {
                string name = System.IO.Path.GetFileNameWithoutExtension(path);
                Assembly assembly = assemblies.FirstOrDefault((item) => { return item.GetName().Name == name; });
                if (assembly == null)
                    assembly = Assembly.LoadFile(path);
                IEnumerable<Type> explist = null;
                try
                {
                    explist = assembly.ExportedTypes;
                }
                catch (Exception ex)
                {
                    LogServiceHelper.Error($"加载{name}.dll程序集失败" + ex.ToString());
                    continue;
                }
                if (null != explist && explist.Count() > 0)
                    catalog.Catalogs.Add(new AssemblyCatalog(assembly));
            }
            CompositionContainer container = new CompositionContainer(catalog);
            container.ComposeParts(this);
            IsInit = true;
        }
        #endregion 公有函数

        #region 私有变量
        private const string SerarchDll = "Vision.*.dll";
        private static object muxe = new object();
        #endregion 私有变量
    }
}
